import json

from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from goods.models import SKU
from meiduo_mall.utils import meiduo_json
from meiduo_mall.utils.response_code import RETCODE
from . import constants


class AddCart(View):

    def post(self, request):
        """添加数据到购物车"""

        # 接收
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        count = data.get('count')
        if not all([sku_id, count]):
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '参数错误'})

        # 验证
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '商品不存在'})

        if count > 5:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '最多只能购买5件商品'})
        elif count < 1:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '购买商品不能少于1个'})
        elif sku.stock < count:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '库存不足'})

        response = JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})

        # 处理
        if request.user.is_authenticated:
            # 保存数据到redis中
            redis = get_redis_connection('carts')
            redis.hincrby('carts:%d' % request.user.id, sku_id, count)
            redis.sadd('selected:%d' % request.user.id, sku_id)

        else:
            # 保存数据到cookie中
            cart_str = request.COOKIES.get('cart')
            if cart_str:
                cart = meiduo_json.loads(cart_str)
            else:
                cart = {}

            if sku_id in cart:
                cart[sku_id] = {
                    'count': cart[sku_id]['count'] + count,
                    'selected': True
                }
            else:
                cart[sku_id] = {
                    'count': count,
                    'selected': True
                }

            cart_str = meiduo_json.dumps(cart)
            response.set_cookie('cart', cart_str, max_age=constants.CART_COOKIE_EXPIRES)

        return response


    def get(self, request):
        """获取购物车数据"""

        cart_skus = []

        if request.user.is_authenticated:
            redis = get_redis_connection('carts')
            data = redis.hgetall('carts:%d' % request.user.id)
            data = {int(k): int(v) for k, v in data.items()}
            selected = redis.smembers('selected:%d' % request.user.id)
            selected = [int(s) for s in selected]
            for sku_id, num in data.items():
                sku = SKU.objects.get(id=sku_id)
                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'count': num,
                    'default_image_url': sku.default_image.url,
                    'selected': str(sku.id in selected),
                    'price': int(sku.price)
                })
        else:
            cart_str = request.COOKIES.get('cart')
            if cart_str:
                cart = meiduo_json.loads(cart_str)
                for k, v in cart.items():
                    sku = SKU.objects.get(id=k)
                    cart_skus.append({
                        'id': sku.id,
                        'name': sku.name,
                        'count': v['count'],
                        'default_image_url': sku.default_image.url,
                        'selected': str(v['selected']),
                        'price': int(sku.price)
                    })

        context = {
            'cart_skus': cart_skus,
        }
        return render(request, 'cart.html', context)


    def put(self, request):
        # 接收
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected')
        if not all([sku_id, count]):
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '参数错误'})

        # 验证
        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '参数错误'})

        if count > 5:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '最多只能购买5件商品'})
        elif count < 1:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '购买商品不能少于1个'})
        elif sku.stock < count:
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '库存不足'})

        # 处理
        cart_sku = {
            'id': sku.id,
            'name': sku.name,
            'count': count,
            'default_image_url': sku.default_image.url,
            'selected': str(selected),
            'price': int(sku.price)
        }
        response = JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'cart_sku': cart_sku})

        if request.user.is_authenticated:
            # 操作redis中数据
            redis = get_redis_connection('carts')
            redis.hset('carts:%d' % request.user.id, sku_id, count)
            if selected:
                redis.sadd('selected:%d' % request.user.id, sku_id)
            else:
                redis.srem('selected:%d' % request.user.id, sku_id)

        else:
            # 操作cookie中数据
            cart_str = request.COOKIES.get('cart')
            cart = meiduo_json.loads(cart_str)
            cart[sku_id] = {
                'count': count,
                'selected': selected
            }
            cart_str = meiduo_json.dumps(cart)
            response.set_cookie('cart', cart_str, max_age=constants.CART_COOKIE_EXPIRES)

        return response

    def delete(self, request):
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        if not all([sku_id]):
            return JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '参数错误'})

        response = JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})
        if request.user.is_authenticated:
            # 操作redis中数据
            redis = get_redis_connection('carts')
            redis.hdel('carts:%d' % request.user.id, sku_id)

        else:
            # 操作cookie中数据
            cart_str = request.COOKIES.get('cart')
            cart = meiduo_json.loads(cart_str)
            if sku_id in cart:
                cart.pop(sku_id)
            cart_str = meiduo_json.dumps(cart)
            response.set_cookie('cart', cart_str, max_age=constants.CART_COOKIE_EXPIRES)

        return response


class CardsSimple(View):

    def get(self, request):
        cart_skus = []

        if request.user.is_authenticated:
            # 从redis中获取数据
            redis = get_redis_connection('carts')
            data = redis.hgetall('carts:%d' % request.user.id)
            data = {int(k): int(v) for k, v in data.items()}
            for sku_id, num in data.items():
                sku = SKU.objects.get(id=sku_id)
                cart_skus.append({
                    'name': sku.name,
                    'count': num,
                    'default_image_url': sku.default_image.url,
                })
        else:
            # 从cookie中获取数据
            cart_str = request.COOKIES.get('cart')
            if cart_str:
                cart = meiduo_json.loads(cart_str)
                for sku_id, v in cart.items():
                    sku = SKU.objects.get(id=sku_id)
                    cart_skus.append({
                        'name': sku.name,
                        'count': v['count'],
                        'default_image_url': sku.default_image.url,
                    })

        return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'cart_skus': cart_skus})


class CardSelectionView(View):

    def put(self, request):
        data = json.loads(request.body.decode())
        selected = data.get('selected')

        response = JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})

        if request.user.is_authenticated:
            # 从redis中获取数据
            redis = get_redis_connection('carts')
            redis_key = 'selected:%d' % request.user.id
            if selected:
                # 先把购物车中的sku_id全部拿出来
                keys = redis.hkeys('carts:%d' % request.user.id)
                redis.sadd(redis_key, *keys)

            else:
                # 全部取消选中
                redis.delete(redis_key)

        else:
            # 从cookie中获取数据
            cart_str = request.COOKIES.get('cart')
            cart = meiduo_json.loads(cart_str)
            for sku_id, v in cart.items():
                cart[sku_id]['selected'] = selected
            cart_str = meiduo_json.dumps(cart)
            response.set_cookie('cart', cart_str, max_age=constants.CART_COOKIE_EXPIRES)

        return response

